import json
from collections import OrderedDict
from pprint import pprint

from django import http
from django.core.paginator import Paginator
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import GoodsChannel, GoodsCategory, SKU
from apps.goods.utils import create_categories, get_breadcrumb
from utils import constants
from utils.response_code import RETCODE


class ListGoodsView(View):
    def get(self, request, category_id, page_num):
        categories_dict = create_categories()
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except:
            return http.HttpResponseNotFound("GoodsCategory does not found")
        # 接收sort参数：如果用户不传，就是默认的排序规则
        sort = request.GET.get('sort', 'default')
        if sort == 'price':
            sort_field = 'price'
        elif sort == 'hot':
            # 按热度降序
            sort_field = '-sales'

        else:
            sort = 'default'
            sort_field = 'create_time'

        # 获取商品信息sku
        skus = SKU.objects.filter(spu__category3=category, is_launched=True).order_by(sort_field)

        # 创建分页器
        paginator = Paginator(skus, constants.GOODS_LIST_LIMIT)
        try:
            page_skus = paginator.page(page_num)
        except:
            return http.HttpResponseNotFound('not found the page')
        total_page = paginator.num_pages

        # 面包屑导航
        breadcrumb = get_breadcrumb(category)
        context = {
            'categories': categories_dict,
            'breadcrumb': breadcrumb,
            'category': category,
            'sort': sort,  # 排序字段
            'page_skus': page_skus,  # 分页后数据
            'page_num': page_num,  # 当前页数
            'total_page': total_page,  # 总页数
        }
        return render(request, 'list.html', context=context)


class HotListView(View):
    def get(self, request, category_id):
        """提供数据排行"""
        # try:
        # 从数据库中查询出该分类的商品排行前二数据(具体数据使用sku)
        # skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
        skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]
        #
        # except:
        #     return http.HttpResponseBadRequest('数据异常')
        hot_skus = []
        for sku in skus:
            hot_skus.append(
                {
                    'id': sku.id,
                    'name': sku.name,
                    'default_image_url': sku.default_image,
                    'price': sku.price,
                }
            )
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})


class DetailView(View):
    def get(self, request, sku_id):
        # 展示商品分类
        categories = create_categories()
        # 查询数据库该商品信息
        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return render(request, '404.html')
        # 查询该商品分类
        category = sku.spu.category3
        # 面包屑导航
        breadcrumb = get_breadcrumb(category)

        # sku规格查询 ******
        spu_specs_dict = {}
        # 查询当前skuid同属spu下的所有的sku  demo：iphone8玫瑰金64G所属的spu iphone8下的所有sku
        all_sku = sku.spu.sku_set.all()
        for sku_temp in all_sku:
            # 所有的当前spu下的sku的规格查询集
            one_sku_specs = sku_temp.specs.all()
            for one_sku_spec in one_sku_specs:
                # 遍历获取每一个sku规格对象
                # print('----sku----', sku_specs.sku_id, '----规格名称----', sku_specs.spec, '----规格选项----', sku_specs.option)
                # print('------规格name------', one_sku_spec.spec.name, '------规格选项name------', one_sku_spec.option.value)
                if (one_sku_spec.spec.name, one_sku_spec.option.value) not in spu_specs_dict:
                    spu_specs_dict[(one_sku_spec.spec.name, one_sku_spec.option.value)] = {sku_temp.id}
                    # print('if---------------', spu_spec_dict)  # {('颜色', '金色'): 3}
                else:
                    spu_specs_dict[(one_sku_spec.spec.name, one_sku_spec.option.value)].add(sku_temp.id)
                    # print('else', spu_specs_dict)

        # pprint(spu_specs_dict.items())
        # {('内存', '256GB'): {8, 4, 6},('内存', '64GB'): {3, 5, 7},('颜色', '深空灰'):{5, 6},('颜色', '金色'): {3, 4},('颜色', '银色'): {8, 7}}

        for op, val in spu_specs_dict.items():
            # print(op, val)
            if sku.id in val:
                set_temp = val - {sku.id}  # 例如 {8, 6}
                spu_specs_dict[op] = {sku.id}  # 例如{4}
                # print('-------1-------', set_temp)
                # print('-------2-------', sku.id)
                # print('-------3-------', spu_specs_dict)
                # {('颜色', '金色'): {3}, ('内存', '64GB'): {3}, ('内存', '256GB'): {4}, ('颜色', '深空灰'): {5, 6},
                # ('颜色', '银色'): {8, 7}}
                # 当前sku下的规格和选项都能获取出来
                for op_2, val_2 in spu_specs_dict.items():
                    for sku_id in set_temp:  # {8, 4}
                        if sku_id in val_2:
                            # print('------4------',val_2)
                            spu_specs_dict[op_2] = {sku_id}
        # demo数据
        # {('内存', '256GB'): {4},
        #  ('内存', '64GB'): {3},
        #  ('颜色', '深空灰'): {6},
        #  ('颜色', '金色'): {4},
        #  ('颜色', '银色'): {8}}

        spu_options = {}
        for op, val in spu_specs_dict.items():
            # print('op-------', op)
            # print('val------', val)
            if op[0] not in spu_options:
                spu_options[op[0]] = [(op[1], val.pop())]
                # print('------------a', spu_options)
            else:
                spu_options[op[0]].append((op[1], val.pop()))

        # pprint(spu_options)

        context = {
            'categories': categories,  # 商品分类字典
            'breadcrumb': breadcrumb,  # 面包屑导航字典
            'sku': sku,
            'specs': spu_options,
            'stock': sku.stock,
        }
        return render(request, 'detail.html', context)


class UserBrowseHistoryView(View):
    """用户浏览记录"""

    def get(self, request):
        """获取商品浏览记录"""
        redis_conn = get_redis_connection('history')
        # 获取当前用户下的浏览记录中的商品id
        sku_ids = redis_conn.lrange('history_%s' % request.user.id, 0, -1)
        skus = []
        for sku_id in sku_ids:
            sku = SKU.objects.get(id=sku_id)
            skus.append(
                {
                    'id': sku.id,
                    'name': sku.name,
                    'default_image': sku.default_image,
                    'price': sku.price,

                }
            )
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'skus': skus})

    def post(self, request):
        """保存用户浏览记录"""
        json_dict = json.loads(request.body.decode())
        sku_id = json_dict.get('sku_id')

        try:
            sku = SKU.objects.get(id=sku_id)
        except:
            return http.HttpResponseBadRequest('数据异常')

        # 保存用户浏览记录
        redis_conn = get_redis_connection('history')
        pl = redis_conn.pipeline()
        user_id = request.user.id

        # 去重
        pl.lrem('history_%s' % user_id, 0, sku_id)

        # 储存
        pl.lpush('history_%s' % user_id, sku_id)

        # 截取    # 只获取5个
        pl.ltrim('history_%s' % user_id, 0, 4)

        # 执行管道 操作
        pl.execute()

        return http.JsonResponse({"code": RETCODE.OK, 'errmsg': 'ok'})
